package com.cysyz.json.fastjson;

import com.alibaba.fastjson.serializer.AfterFilter;
import com.alibaba.fastjson.serializer.BeforeFilter;
import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.NameFilter;
import com.alibaba.fastjson.serializer.PropertyFilter;
import com.alibaba.fastjson.serializer.PropertyPreFilter;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializeFilter;
import com.alibaba.fastjson.serializer.SerializeWriter;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer;
import com.alibaba.fastjson.serializer.ValueFilter;
import com.cysyz.json.framework.IJsonConfig;
import com.cysyz.json.framework.IJsonGenerator;
import com.cysyz.json.framework.JSONResult;
import com.cysyz.json.framework.ResultType;
import com.cysyz.mylib.utils.strings.wraper.StringWrapper;

import java.util.Date;
import java.util.List;

public class JSONGeneratorFastJson implements IJsonGenerator {

	public static final String DATE_TIME = "yyyy-MM-dd HH:mm:ss";

	private static SerializeConfig mapping = new SerializeConfig();

	private StringWrapper jsonWrapper;
	private PropertyFilter filter = new HibernatePropertyFilter();
	private PropertyPreFilter preFilter = new ComplexPropertyPreFilter();

	public JSONGeneratorFastJson() {
		this.jsonWrapper = new StringWrapper() {
			@Override
			public String wrap(String json) {
				return json;
			}
		};
	}

	public JSONGeneratorFastJson(StringWrapper jsonWraper) {
		super();
		this.jsonWrapper = jsonWraper;
	}

	public String generateJSON(ResultType result, List<Object> content, IJsonConfig jsonConfig) {
		return generateJSON0(result, content, jsonConfig);
	}

	@Override
	public String generateJSON(Object content, IJsonConfig jsonConfig) {
		return this.generateJSON0(null, content, jsonConfig);
	}

	private String generateJSON0(ResultType result, Object content, IJsonConfig jsonConfig) {
        /*设置hibernate代理类中应该不进行json序列话的属性名称 结束*/

		Object jsonResult = content;
		if (content instanceof List) {
			jsonResult = new JSONResult(result, (List<Object>) content);
		}
		mapping.put(Date.class, new SimpleDateFormatSerializer(DATE_TIME));

		String text = this.toJsonString(jsonResult, mapping, SerializerFeature.WriteNullStringAsEmpty, SerializerFeature.WriteMapNullValue);
		if (jsonWrapper != null) {
			text = jsonWrapper.wrap(text);
		}
		return text;
	}

	private String toJsonString(Object object, SerializeConfig config, SerializerFeature... features) {
		SerializeWriter out = new SerializeWriter();

		try {
			JSONSerializer serializer = new JSONSerializer(out, config);
			SerializerFeature[] serializerFeatures = features;
			int len = features.length;

			for(int i = 0; i < len; ++i) {
				SerializerFeature feature = serializerFeatures[i];
				serializer.config(feature, true);
			}

			serializer.config(SerializerFeature.WriteDateUseDateFormat, true);
			configFilter(serializer, preFilter);
			configFilter(serializer, filter);

			serializer.write(object);
			String result = out.toString();
			return result;
		} finally {
			out.close();
		}
	}

	private void configFilter(JSONSerializer serializer, SerializeFilter filter) {
		if(filter != null) {
            if(filter instanceof PropertyPreFilter) {
                serializer.getPropertyPreFilters().add((PropertyPreFilter)filter);
            }

            if(filter instanceof NameFilter) {
                serializer.getNameFilters().add((NameFilter)filter);
            }

            if(filter instanceof ValueFilter) {
                serializer.getValueFilters().add((ValueFilter)filter);
            }

            if(filter instanceof PropertyFilter) {
                serializer.getPropertyFilters().add((PropertyFilter)filter);
            }

            if(filter instanceof BeforeFilter) {
                serializer.getBeforeFilters().add((BeforeFilter)filter);
            }

            if(filter instanceof AfterFilter) {
                serializer.getAfterFilters().add((AfterFilter)filter);
            }
        }
	}

	private IJsonConfig setJsonConfig(IJsonConfig jsonConfig) {
		return null;
	}

	public String generateJSON(ResultType result, List<Object> content) {
		return this.generateJSON(result, content, null);
	}
}
